package com.panfeng.xcloud.boss.provider.member.security.verifyCode;

import com.panfeng.xcloud.boss.provider.member.security.SecurityConstants;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.authentication.AuthenticationServiceException;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 *
 * 自定义security短信登录过滤器
 *
 * @author xiaobo
 * @version 1.0
 * @since 2018-12-28
 */
@Slf4j
public class VerifyCodeAuthenticationFilter extends AbstractAuthenticationProcessingFilter {

	private static final String POST = "POST";

	private String mobileParameter = SecurityConstants.DEFAULT_PARAMETER_NAME_MOBILE;
	private String verifyCodeParameter = SecurityConstants.DEFAULT_PARAMETER_NAME_VERIFYCODE;

	private String clientIdParameter = SecurityConstants.DEFAULT_PARAMETER_NAME_CLIENTID;
	private String clientSecretParameter = SecurityConstants.DEFAULT_PARAMETER_NAME_CLIENTSECRET;

	private boolean postOnly = true;

	public VerifyCodeAuthenticationFilter() {
		super(new AntPathRequestMatcher(SecurityConstants.DEFAULT_VERIFYCODE_LOGIN_URL, "POST"));
	}

	@Override
	public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response)
			throws AuthenticationException {
		if (postOnly && !POST.equals(request.getMethod())) {
			throw new AuthenticationServiceException("Authentication method not supported: " + request.getMethod());
		}
		log.info(">>>> 开始执行VerifyCodeAuthenticationFilter过滤器，开始获取鉴权信息<<<");
		String grantType = getGrantType(request);
		if (StringUtils.isEmpty(grantType)) {
			grantType = "";
		}
		String mobile = getMobileNo(request);
		if (StringUtils.isEmpty(mobile)) {
			mobile = "";
		}
		String verifyCode = getVerifyCode(request);
		if (StringUtils.isEmpty(verifyCode)) {
			verifyCode = "";
		}
		String clientId = getClientId(request);
		if (StringUtils.isEmpty(clientId)) {
			clientId = "";
		}
		String clientSecret = getClientSecret(request);
		if (StringUtils.isEmpty(clientSecret)) {
			clientSecret = "";
		}
		grantType = grantType.trim();
		mobile = mobile.trim();
		verifyCode = verifyCode.trim();
		clientId = clientId.trim();
		clientSecret = clientSecret.trim();
		VerifyCodeAuthenticationToken authRequest = new VerifyCodeAuthenticationToken(grantType + "_" + mobile + "_" + verifyCode +"_"+ clientId +"_" + clientSecret);
		log.info(">>>> 已经执行VerifyCodeAuthenticationFilter过滤器完毕，VerifyCodeAuthenticationToken信息：{}<<<",authRequest);
		setDetails(request, authRequest);
		return this.getAuthenticationManager().authenticate(authRequest);
	}

	private String getGrantType(HttpServletRequest request) {
		return request.getParameter("grant_type");
	}

	private String getClientSecret(HttpServletRequest request) {
		return request.getParameter(clientSecretParameter);
	}

	private String getClientId(HttpServletRequest request) {
		return request.getParameter(clientIdParameter);
	}

	protected String getMobileNo(HttpServletRequest request) {
		return request.getParameter(mobileParameter);
	}

	protected String getVerifyCode(HttpServletRequest request) {
		return request.getParameter(verifyCodeParameter);
	}

	protected void setDetails(HttpServletRequest request, VerifyCodeAuthenticationToken authRequest) {
		authRequest.setDetails(authenticationDetailsSource.buildDetails(request));
	}

	public String getMobileParameter() {
		return mobileParameter;
	}

	public void setMobileParameter(String mobileParameter) {
		Assert.hasText(mobileParameter, "用户手机号参数没有设置mobileNo");
		this.mobileParameter = mobileParameter;
	}

	public String getVerifyCodeParameter() {
		return verifyCodeParameter;
	}

	public void setVerifyCodeParameter(String verifyCodeParameter) {
		Assert.hasText(mobileParameter, "用户验证码参数没有设置verifyCode");
		this.verifyCodeParameter = verifyCodeParameter;
	}

	public String getClientIdParameter() {
		return clientIdParameter;
	}

	public void setClientIdParameter(String clientIdParameter) {
		Assert.hasText(clientIdParameter, "没有设置clientId参数");
		this.clientIdParameter = clientIdParameter;
	}

	public String getClientSecretParameter() {
		return clientSecretParameter;
	}

	public void setClientSecretParameter(String clientSecretParameter) {
		Assert.hasText(clientIdParameter, "没有设置clientSecret参数");
		this.clientSecretParameter = clientSecretParameter;
	}

	public void setPostOnly(boolean postOnly) {
		this.postOnly = postOnly;
	}

}
